package com.spartez.farhorizons.server;

import java.io.InvalidClassException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.datanucleus.exceptions.NucleusException;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.spartez.farhorizons.client.GreetingService;
import com.spartez.farhorizons.client.attic.SpeciesDescr;
import com.spartez.farhorizons.client.data.ISystemDescr;
import com.spartez.farhorizons.client.data.SystemDescr;
import com.spartez.farhorizons.server.dao.PlayerData;


/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
		GreetingService {

	public String getUserName() {
		UserService userService = UserServiceFactory.getUserService();
		return userService.getCurrentUser().getNickname();
	}

	public Collection<SpeciesDescr> getVisibleSpecies() {
		return new ArrayList<SpeciesDescr>();
	}

	public Collection<? extends ISystemDescr> parseStarList(String list) {
		Collection<SystemDescr> stars = new ArrayList<SystemDescr>();
		Pattern starPattern = Pattern.compile("x = (\\d+)\\s+y = (\\d+)\\s+z = (\\d+)\\s+stellar type =\\s+(\\S+)");
		Matcher m = starPattern.matcher(list);
		while (m.find()) {
			SystemDescr sd = new SystemDescr(
					Integer.valueOf(m.group(1)),
					Integer.valueOf(m.group(2)),
					Integer.valueOf(m.group(3)),
					m.group(4));
			stars.add(sd);
		}
		
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			final PlayerData playerData = getPlayerDataObj(pm, UserServiceFactory.getUserService().getCurrentUser());
			playerData.setSystemDescrs(stars);
		} finally {
			pm.close();
		}
		return stars;
	}

	public Collection<? extends ISystemDescr> getStarList() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			PlayerData playerData = getPlayerDataObj(pm, UserServiceFactory.getUserService().getCurrentUser());
			return playerData.getSystemDescrs();
		} finally {
			pm.close();
		}
	}
	
	@SuppressWarnings("unchecked")
	private PlayerData getPlayerDataObj(PersistenceManager pm, User user) {
		Query query = pm.newQuery(PlayerData.class);
		query.setFilter("owner == user");
		query.declareParameters(User.class.getName() + " user");
		
		List<PlayerData> result = (List<PlayerData>) query.execute(user);
		final PlayerData playerData;
		boolean needsRecreate = false;
		
		try {
			needsRecreate = result.isEmpty();
		} catch (NucleusException ex) {
			needsRecreate = true;
		}
		if (needsRecreate) {
			playerData = new PlayerData(user);
			pm.makePersistent(playerData);
		} else {
			playerData = result.get(0);
		}
		return playerData;
	}
}
